﻿using System.Collections.Generic;
using System.Linq;
using Model.Entities;
using Model.Repositories;

namespace Presenter.Users
{
    public class UserMessagesPresenter
    {
        private IUserMessagesView _view;

        public UserMessagesPresenter(IUserMessagesView view, int id)
        {
            _view = view;

            _view.GetSentMessages(GetSentMessages(id));
            _view.GetReceivedMessages(GetReceivedMessages(id));

            _view.EntitySentDeleted += ViewEntitySentDeleted;
            _view.EntityReceiveDeleted += ViewEntityReceiveDeleted;
            _view.EntityCreated += ViewEntityCreated;

            _view.GetAllUsers(GetAllUsers(id));
        }

        public UserMessagesPresenter(IUserMessagesView view, string email, string password)
        {
            _view = view;

            _view.GetSentMessages(GetSentMessages(email, password));
            _view.GetReceivedMessages(GetReceivedMessages(email, password));

            _view.EntitySentDeleted += ViewEntitySentDeleted;
            _view.EntityReceiveDeleted += ViewEntityReceiveDeleted;
            _view.EntityCreated += ViewEntityCreated;

            _view.GetAllUsers(GetAllUsers(email));
        }

        void ViewEntityCreated(string email, string password, int id, string title, string text)
        {
            var obj  = RepositoryManager.Instance.UserRepository.GetByEmailAndPassword(email, password);
            var obj1 = RepositoryManager.Instance.UserRepository.Get(id);
            if (obj != null && obj1 != null)
            {
                obj.UserSentMessages.Add(new UserMessage
                                             {
                                                 Sender     = obj,
                                                 Text       = text,
                                                 Title      = title,
                                                 Receiver   = obj1
                                             });
                RepositoryManager.Instance.UserRepository.Update(obj);
            }
        }

        void ViewEntitySentDeleted(string email, string password, int id)
        {
            var obj = RepositoryManager.Instance.UserRepository.GetByEmailAndPassword(email, password);
            if (obj != null)
            {
                var message = obj.UserSentMessages.FirstOrDefault(o => o.Id == id);
                if (message != null)
                {
                    message.DeletedBySender = true;
                    RepositoryManager.Instance.UserRepository.Update(obj);
                }
            }
        }

        void ViewEntityReceiveDeleted(string email, string password, int id)
        {
            var obj = RepositoryManager.Instance.UserRepository.GetByEmailAndPassword(email, password);
            if (obj != null)
            {
                var message = RepositoryManager.Instance.UserMessageRepository.Get(id);
                if (message != null && message.Receiver.Id == obj.Id)
                {
                    message.DeletedByReceiver = true;
                    RepositoryManager.Instance.UserRepository.Update(obj);
                }
            }
        }

        public void Reload(IUserMessagesView view, int id)
        {
            _view = view;

            _view.GetSentMessages(GetSentMessages(id));
            _view.GetReceivedMessages(GetReceivedMessages(id));

            _view.EntitySentDeleted += ViewEntitySentDeleted;
            _view.EntityReceiveDeleted += ViewEntityReceiveDeleted;
            _view.EntityCreated += ViewEntityCreated;

            _view.GetAllUsers(GetAllUsers(id));
        }

        public void Reload(IUserMessagesView view, string email, string password)
        {
            _view = view;

            _view.GetSentMessages(GetSentMessages(email, password));
            _view.GetReceivedMessages(GetReceivedMessages(email, password));

            _view.EntitySentDeleted += ViewEntitySentDeleted;
            _view.EntityReceiveDeleted += ViewEntityReceiveDeleted;
            _view.EntityCreated += ViewEntityCreated;

            _view.GetAllUsers(GetAllUsers(email));
        }

        private Dictionary<int, string> GetAllUsers(int id)
        {
            var users = RepositoryManager.Instance.UserRepository.GetAll();
            if (users != null)
            {
                return users.Where(user => user.Id != id).ToDictionary(user => user.Id, user => user.Email);
            }
            return null;
        }

        private Dictionary<int, string> GetAllUsers(string email)
        {
            var users = RepositoryManager.Instance.UserRepository.GetAll();
            if (users != null)
            {
                return users.Where(user => user.Email != email).ToDictionary(user => user.Id, user => user.Email);
            }
            return null;
        }

        List<List<string>> GetSentMessages(int id)
        {
            var result = new List<List<string>>();

            var obj = RepositoryManager.Instance.UserRepository.Get(id);
            if (obj != null && obj.UserSentMessages.Where(message => message.DeletedBySender == false).Count() != 0)
            {
                result.AddRange(obj.UserSentMessages.Where(message => message.DeletedBySender == false).Select(message => new List<string> { message.Id.ToString(), message.Receiver.Id.ToString(), message.Title, message.Text, message.SentDateTime.ToString() }));
            }

            return result;
        }

        List<List<string>> GetSentMessages(string email, string password)
        {
            var result = new List<List<string>>();

            var obj = RepositoryManager.Instance.UserRepository.GetByEmailAndPassword(email, password);
            if (obj != null && obj.UserSentMessages.Where(message => message.DeletedBySender == false).Count() != 0)
            {
                result.AddRange(obj.UserSentMessages.Where(message => message.DeletedBySender == false).Select(message => new List<string> { message.Id.ToString(), message.Receiver.Id.ToString(), message.Title, message.Text, message.SentDateTime.ToString() }));
            }

            return result;
        }

        List<List<string>> GetReceivedMessages(int id)
        {
            var result = new List<List<string>>();

            var obj = RepositoryManager.Instance.UserRepository.Get(id);
            if (obj != null)
            {
                result.AddRange(RepositoryManager.Instance.UserMessageRepository.GetAll().Where(message => message.DeletedByReceiver == false && message.Receiver.Id == obj.Id).Select(message => new List<string> { message.Id.ToString(), message.Sender.Id.ToString(), message.Title, message.Text, message.SentDateTime.ToString() }));
            }

            return result;
        }

        List<List<string>> GetReceivedMessages(string email, string password)
        {
            var result = new List<List<string>>();

            var obj = RepositoryManager.Instance.UserRepository.GetByEmailAndPassword(email, password);
            if (obj != null)
            {
                result.AddRange(RepositoryManager.Instance.UserMessageRepository.GetAll().Where(message => message.DeletedByReceiver == false && message.Receiver.Id == obj.Id).Select(message => new List<string> { message.Id.ToString(), message.Sender.Id.ToString(), message.Title, message.Text, message.SentDateTime.ToString() }));
            }

            return result;
        }
    }
}

